import json
import os
import threading
import uuid
from typing import Dict

from loguru import logger

from utils import model, utils
from tts import read

__dir__ = os.path.dirname(__file__)


class Business:
    _instance_lock = threading.Lock()
    __first_init = None

    def __new__(cls, *args, **kwargs):
        if not hasattr(Business, "_instance"):
            with Business._instance_lock:
                if not hasattr(Business, "_instance"):
                    # 类加括号就回去执行__new__方法，__new__方法会创建一个类实例：Singleton()
                    # 继承object类的__new__方法，类去调用方法，说明是函数，要手动传cls
                    Business._instance = object.__new__(cls)
        return Business._instance  # obj1

    def __init__(self):
        if not self.__first_init:
            self.role_config_path = os.path.join(__dir__, '../setting/role_config.ini')
            self.support_tts = read.read_support_md()
            self.role_config_model = self._get_role_model()
            self.text_dict: Dict[int, model.ListItem] = {}
            # 存放所有的自定义列表对象，用来整体播放的时候触发play
            self.item_list = []
            self.output_dir = os.path.abspath(os.path.join(__dir__, '../../output/'))
            Business.__first_init = True

    def _get_role_model(self) -> Dict[str, model.RoleConfig]:
        role_config = utils.parse_ini(self.role_config_path)
        return {name: model.RoleConfig(**config) for name, config in role_config.items()}

    def write_role_model(self):
        value = {name: dict(_model)
                 for name, _model in self.role_config_model.items()}
        utils.write_ini(self.role_config_path, value)

    @staticmethod
    def get_tts_uuid_name(value_dict: dict):
        role_str = json.dumps(value_dict)
        uuid_str = str(uuid.uuid3(uuid.NAMESPACE_DNS, role_str))
        return uuid_str

    def get_abs_tts_full_path(self, tts_uuid_name):
        file_name = '{}.mp3'.format(tts_uuid_name)
        path = os.path.abspath(os.path.join(self.output_dir, file_name))
        return path

    def get_tts_uuid_base_name(self, count):
        role_name = self.text_dict[count].role
        text = self.text_dict[count].text
        role_dict = dict(self.role_config_model[role_name])
        role_dict['text'] = text
        uuid_str = self.get_tts_uuid_name(role_dict)
        return uuid_str

    def get_tts_path_uuid(self, count):
        uuid_str = self.get_tts_uuid_base_name(count)
        tts_path_uuid = self.get_abs_tts_full_path(uuid_str)
        logger.info("count={} tts_uuid={}, tts_full_path={}".format(count, uuid_str, tts_path_uuid))
        return tts_path_uuid
